     /*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.brain.prod.mbean;

import com.brain.conf.dto.UnidadMedidaDto;
import com.brain.conf.manager.UnidadMedidaManager;
import com.brain.core.common.UtilCore;
import com.brain.core.configuracion.WebServletContextListener;
import com.brain.core.dto.ParametroDto;
import com.brain.core.exception.DAOException;
import com.brain.core.manager.BitacoraManager;
import com.brain.core.manager.ParametroManager;
import com.brain.core.manager.RecursosManager;
import com.brain.core.view.mbean.ApplicationMBean;
import com.brain.core.view.mbean.ArchivoMBean;
import com.brain.core.view.mbean.GenericMBean;
import com.brain.core.view.mbean.SessionMBean;
import com.brain.prod.dto.OrdenFabDto;
import com.brain.prod.dto.OrdenFabOperacionDto;
import com.brain.prod.dto.OrdenFabProductoDto;
import com.brain.prod.dto.ParteTrabajoDto;
import com.brain.prod.dto.PlanProduccionDto;
import com.brain.prod.dto.PlanProduccionOperacionDto;
import com.brain.prod.dto.ProcesoDto;
import com.brain.prod.manager.OrdenFabOperacionManager;
import com.brain.prod.manager.OrdenFabProductoManager;
import com.brain.prod.manager.OrdenFabricacionManager;
import com.brain.prod.manager.PlanProduccionManager;
import com.brain.prod.manager.PlanProduccionOperacionManager;
import com.brain.prod.manager.ProcesoManager;
import com.brain.prod.view.util.ConstantesProd;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
import javax.annotation.Resource;
import javax.faces.event.ActionEvent;
import org.apache.log4j.Logger;
import org.primefaces.context.RequestContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

/**
 * @author Greip Company
 * @since 09/01/2014
 * @version 1.0
 */
@Controller("ordenFabricacionMBean")
@Scope("session")
public class OrdenFabricacionMBean extends GenericMBean implements Serializable {

    /**
     * Logger permite registrar los errores que ocurren
     *
     * @since 09/01/2014
     */
    private static Logger logger = Logger.getLogger(OrdenFabricacionMBean.class);
    /**
     * manager: comunica a la vista con la capa de negocio de la entidad
     * OrdenFabDto
     *
     * @since 10/01/2014
     */
    @Resource
    private OrdenFabricacionManager manager;
    /**
     * opManager: comunica a la vista con la capa de negocio de la entidad
     * OrdenFabOperacionDto
     *
     * @since 10/01/2014
     */
    @Resource
    private OrdenFabOperacionManager opManager;
    /**
     * prodManager: comunica a la vista con la capa de negocio de la entidad
     * OrdenFabProductoDto
     *
     * @since 10/01/2014
     */
    @Resource
    private OrdenFabProductoManager prodManager;
    /**
     * applicationMBean permite obtener diferentes valores de la aplicación,
     * como acciones y estilos
     *
     * @since 09/01/2014
     */
    @Autowired
    private ApplicationMBean applicationMBean;
    /**
     * sessionMBean: contiene información del usuario, asi como las acciones que
     * se realizan sobre la entidad
     *
     * @since 10/01/2014
     */
    @Autowired
    private SessionMBean sessionMBean;
    /**
     * recursosManager permite mostrar mensajes en las vistas
     *
     * @since 09/01/2014
     */
    @Resource
    private RecursosManager recursosManager;
    /**
     * bitacoraManager: permite desplegar un popup con las acciones que se
     * realizaron sobre la entidad
     *
     * @since 10/01/2014
     */
    @Resource
    private BitacoraManager bitacoraManager;
    @Resource
    private ArchivoMBean archivoMBean;
    /**
     * lista: almacena el listado de registros de la entidad OrdenFabDto. Usada
     * en la vista listaOrdenFabricacion.xhtml
     *
     * @since 10/01/2014
     */
    private List<OrdenFabDto> lista;
    /**
     * dto: almacena los datos provenientes de la vista ordenFabricacion.xhtml
     *
     * @since 10/01/2014
     */
    private OrdenFabDto dto;
    /**
     * dtoFiltro: almacena los datos provenientes de la vista
     * listaOrdenFabricacion.xhtml
     *
     * @since 10/01/2014
     */
    private OrdenFabDto dtoFiltro;
    /**
     * detaOpDto: almacena los datos de la entidad OrdenFabOperacionDto
     *
     * @since 10/01/2014
     */
    private OrdenFabOperacionDto detaOpDto;
    /**
     * detaProdDto: almacena los datos de la entidad OrdenFabProductoDto
     *
     * @since 10/01/2014
     */
    private OrdenFabProductoDto detaProdDto;
    /**
     * keyTitulo: variable que almacena el titulo de los paneles de la entidad
     *
     * @since 10/01/2014
     */
    private String keyTitulo = "form.orden.fabricacion";
    /**
     * listaPlanProduccion: variable utilizada para cargar el combo de la
     * entidad PlanProduccionDto
     *
     * @since 10/01/2014
     */
    private List<PlanProduccionDto> listaPlanProduccion;
    /**
     * listaOperacion: variable utilizada para cargar el combo de la entidad
     * PlanProduccionOperacionDto
     *
     * @since 10/01/2014
     */
    private List<PlanProduccionOperacionDto> listaOperacion;
    /**
     * listaProceso: variable utilizada para cargar el combo de la entidad
     * ProcesoDto
     *
     * @since 10/01/2014
     */
    private List<ProcesoDto> listaProceso;
    /**
     * listaTipoProducto: variable utilizada para cargar el combo de tipos de
     * producto
     *
     * @since 10/01/2014
     */
    private List<ParametroDto> listaTipoProducto;
    /**
     * listaUom: variable utilizada para cargar el combo de la entidad
     * UnidadMedidaDto
     *
     * @since 10/01/2014
     */
    private List<UnidadMedidaDto> listaUom;
    /**
     * parteTrabajoDto: variable que almacena el parte de trabajo generado a
     * partir de una orden de fabricación
     *
     * @since 10/01/2014
     */
    private ParteTrabajoDto parteTrabajoDto;

    /**
     * iniciar(): inicializa las variable dtoFiltro y lista
     *
     * @return retorna la dirección de la vista listaOrdenFabricacion.xhtml
     */
    public String iniciar() {
        this.dtoFiltro = new OrdenFabDto();
        this.lista = null;
        return this.manager.getUrlLista();
    }

    /**
     * buscar(ae): realiza la búsqueda de registros de la entidad OrdenFabDto y
     * lo asigna a la variable lista
     *
     * @since: 10/01/2014
     * @param ae por defecto null
     */
    public void buscar(ActionEvent ae) {
        try {
            this.lista = this.manager.obtenerOrdenFabricacion(this.dtoFiltro);
        } catch (DAOException ex) {
            logger.error(ex);
        }
    }

    /**
     * inicializar(): se encarga de inicializar la entidad OrdenFabDto
     *
     * @since 10/01/2014
     * @throws DAOException
     */
    public void inicializar() throws DAOException {
        this.dto = this.manager.inicializar();
        this.dto = this.manager.obtenerDatosDePlanProduccion(this.dto, getListaPlanProduccion());
    }

    /**
     * nuevo(): setea la accion a nuevo, crea el titulo del panel entidad e
     * inicializa las entidades
     *
     * @since 10/01/2014
     * @return retorna la dirección de la vista ordenFabricacion.xhtml
     */
    public String nuevo() throws DAOException {
        sessionMBean.setAccion(applicationMBean.getNuevo());
        sessionMBean.setTitulo(recursosManager.construirTitulo(keyTitulo, sessionMBean.getAccion()));
        inicializar();
        return this.manager.getUrl();
    }

    /**
     * nuevaOperacion(): setea la accionDetalle a nuevo, crea el titulo del
     * panel entidadDetalle e inicializa la entidad detalle. Asigna a la entidad
     * detalle la referencia de la entidad padre
     *
     * @since 10/01/2014
     */
    public void nuevaOperacion() {
        sessionMBean.setAccionDetalle(applicationMBean.getNuevo());
        this.detaOpDto = this.opManager.inicializar();
        this.detaOpDto.setOrdenFabDto(this.dto);
    }

    /**
     * nuevoProducto(): setea la accionDetalle a nuevo, crea el titulo del panel
     * entidadDetalle e inicializa la entidad detalle. Asigna a la entidad
     * detalle la referencia de la entidad padre
     *
     * @since 10/01/2014
     */
    public void nuevoProducto() {
        this.detaProdDto = this.prodManager.inicializar();
        this.detaProdDto.setAccionNvl3(applicationMBean.getNuevo());
        this.detaProdDto.setOrdenFabOperacionDto(this.detaOpDto);
    }

    /**
     * editar(): setea la accion a editar, crea el titulo del panel de la
     * entidad e inicializa las entidades detalle
     *
     * @since 10/01/2014
     * @return retorna la direccion de la vista ordenFabricacion.xhtml
     */
    public String editar() {
        sessionMBean.setAccion(applicationMBean.getEditar());
        sessionMBean.setTitulo(recursosManager.construirTitulo(keyTitulo, sessionMBean.getAccion()));
        return this.manager.getUrl();
    }

    /**
     * editarOperacion(): setea la accionDetalle a editar, crea el titulo del
     * panel de la entidad detalle y obtiene la entidadDetalle
     *
     * @since 10/01/2014
     */
    public void editarOperacion() {
        sessionMBean.setAccionDetalle(applicationMBean.getEditar());
        if (this.detaOpDto.getId() != null) {
            try {
                this.detaOpDto = this.opManager.obtenerPorId(this.detaOpDto.getId());
            } catch (DAOException e) {
                showError(e.getMessage());
                logger.error(e);
            }
        }
    }

    /**
     * editarProducto(): setea la accionDetalle a editar, crea el titulo del
     * panel de la entidad detalle y obtiene la entidadDetalle
     *
     * @since 10/01/2014
     */
    public void editarProducto() {
        if (this.detaProdDto.getId() != null) {
            try {
                this.detaProdDto = this.prodManager.obtenerPorId(this.detaProdDto.getId());
                this.detaProdDto.setAccionNvl3(applicationMBean.getEditar());
            } catch (DAOException e) {
                showError(e.getMessage());
                logger.error(e);
            }
        }
    }

    /**
     * ver(): setea la accion a ver, crea el titulo del panel de la entidad e
     * inicializa las entidades detalle
     *
     * @since 10/01/2014
     * @return retorna la dirección de la vista ordenFabricacion.xhtml
     */
    public String ver() {
        sessionMBean.setAccion(applicationMBean.getVer());
        sessionMBean.setTitulo(recursosManager.construirTitulo(keyTitulo, sessionMBean.getAccion()));
        return this.manager.getUrl();
    }

    /**
     * verOperacion(): setea la accionDetalle a ver, crea el titulo del panel de
     * la entidad detalle y obtiene la entidad detalle
     *
     * @since 10/01/2014
     */
    public void verOperacion() {
        sessionMBean.setAccionDetalle(applicationMBean.getVer());
        if (this.detaOpDto.getId() != null) {
            try {
                this.detaOpDto = this.opManager.obtenerPorId(this.detaOpDto.getId());
            } catch (DAOException e) {
                showError(e.getMessage());
                logger.error(e);
            }
        }
    }

    /**
     * verProducto(): setea la accionDetalle a ver, crea el titulo del panel de
     * la entidad detalle y obtiene la entidad detalle
     *
     * @since 10/01/2014
     */
    public void verProducto() {
        if (this.detaProdDto.getId() != null) {
            try {
                this.detaProdDto = this.prodManager.obtenerPorId(this.detaProdDto.getId());
                this.detaProdDto.setAccionNvl3(applicationMBean.getVer());
            } catch (DAOException e) {
                showError(e.getMessage());
                logger.error(e);
            }
        }
    }

    /**
     * Metodo guardar() se encarga de guardar la entidad OrdenFabDto y devuelve
     * null como valor de cadena
     *
     * @since 10/01/2014
     * @return retorna null como valor de cadena
     */
    public String guardar() {
        if (!this.manager.existeNroDocumento(this.dto.getNroDocumento()) || sessionMBean.getAccion() != applicationMBean.getNuevo()) {
            if (this.manager.guardar(this.dto) != null) {
                this.editar();
            }
        } else {
            recursosManager.showError(UtilCore.Internacionalizacion.getMensajeInternacional("orden.fab.existe.nro.documento"));
        }
        return null;
    }

    /**
     * guardarOperacion(): permite guardar la entidad MaquinaCostoDto; a la vez,
     * obtiene la entidad OrdenFabDto
     *
     * @since 10/01/2014
     */
    public void guardarOperacion() {
        RequestContext context = RequestContext.getCurrentInstance();
        boolean resultado = true;
        try {
            if (this.opManager.guardar(this.detaOpDto) != null) {
                this.dto = this.manager.obtenerPorId(this.dto.getId());
                actualizarTiempoEstimado();
                this.dto = this.manager.obtenerPorId(this.dto.getId());
            } else {
                resultado = false;
            }
        } catch (DAOException e) {
            showError("ERROR_SISTEMA", e.getMessage());
            logger.error(e);
        }
        System.out.println("RESULTADO -->" + resultado);
        context.addCallbackParam("CallbackParam", resultado);
    }

    /**
     * actualizarTiempoEstimado(): contabiliza los tiempos de cada operación
     *
     * @since 10/01/2014
     */
    public void actualizarTiempoEstimado() {
        Integer suma = 0;
        for (OrdenFabOperacionDto x : this.dto.getListaOperaciones()) {
            suma = suma + x.getTiempoEstimado();
        }
        this.dto.setTiempoEstimado(new BigDecimal(suma.toString()));
        this.manager.actualizarOrdenFabricacion(this.dto);
    }

    /**
     * guardarProducto(): permite guardar la entidad OrdenFabProductoDto; a la
     * vez, obtiene la entidad OrdenFabOperacionDto
     *
     * @since 10/01/2014
     */
    public void guardarProducto() {
        RequestContext context = RequestContext.getCurrentInstance();
        boolean resultado = true;
        if (this.prodManager.verificarStock(this.detaProdDto)) {
            try {
                if (this.prodManager.guardar(this.detaProdDto) != null) {
                    this.detaOpDto = this.opManager.obtenerPorId(this.detaOpDto.getId());
                } else {
                    resultado = false;
                }
            } catch (DAOException e) {
                showError("ERROR_SISTEMA", e.getMessage());
                logger.error(e);
            }
        } else {
            resultado = false;
            recursosManager.showMessage(UtilCore.Internacionalizacion.getMensajeInternacional("orden.fab.no.suficiente.stock"));
        }
        context.addCallbackParam("CallbackParam", resultado);
    }

    /**
     * verBitacora(): método encargado de mostrar un popup con las acciones
     * realizadas sobre la entidad
     *
     * @since 10/01/2014
     * @return retorna null
     */
    public String verBitacora() {
        bitacoraManager.cargarBitacoraEntidad(manager.getIdEntidad(), this.dto.getId());
        return null;
    }

    /**
     * retroceder(): retorna a la pagina listaOrdenFabricacion.xhtml mostrando
     * el listado de todos los registros
     *
     * @since 10/01/2014
     * @return retorna la dirección de la vista listaOrdenFabricacion.xhtml
     */
    public String retroceder() {
        buscar(null);
        return this.manager.getUrlLista();
    }

    /**
     * onBlurCalcularCantidad(): asigna la cantidad equivalente a la division de
     * la cantidad proceso entre el radio de conversión
     *
     * @since 10/01/2014
     */
    public void onBlurCalcularCantidad() {
        this.dto.setCantidad(this.dto.getCantidadProceso().divide(this.dto.getRadioConversion()));
    }

    /**
     * onChangePlanProduccion(): actualiza la entidad al seleccionar otro plan
     * de producción
     *
     * @since 10/01/2014
     */
    public void onChangePlanProduccion() {
        this.dto = this.manager.onChangePlanProduccion(this.dto);
    }

    /**
     * explotarFases(): extrae las operacion y productos del plan de producción
     * y los guarda en la orden de fabricación
     *
     * @since 10/01/2014
     */
    public void explotarFases() {
        this.manager.explotarFases(this.dto);
        try {
            this.dto = this.manager.obtenerPorId(this.dto.getId());
        } catch (DAOException e) {
            logger.error(e.getMessage());
        }
    }

    /**
     * confirmar(): confirma una orden de fabricación, cambiando su estado a
     * confirmado. Actualiza la entidad OrdenFabDto
     *
     * @since 10/01/2014
     */
    public void confirmar() {
        if (this.manager.validarDetalles(this.dto)) {
            this.dto.setEstado(ConstantesProd.ValoresConstantes.ORDEN_FABRICACION_COD_CONFIRMADO);
            this.manager.actualizarOrdenFabricacion(this.dto);
            try {
                this.dto = this.manager.obtenerPorId(this.dto.getId());
                showMessage(UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok"));
            } catch (DAOException e) {
                logger.error(e.getMessage());
            }
        }
    }

    /**
     * generarParteTrabajo(): genera un parte de trabajo a partir de una orden
     * de fabricación.
     *
     * @since 10/01/2014
     */
    public void generarParteTrabajo() {
        sessionMBean.setAccionDetalle(applicationMBean.getNuevo());
        this.parteTrabajoDto = this.manager.generarParteTrabajo(this.dto);
    }

    /**
     * guardarParteTrabajo(): guarda el parte de trabajo, una vez que han sido
     * llenado los detalles del mismo
     *
     * @since 10/01/2014
     */
    public void guardarParteTrabajo() {
        RequestContext context = RequestContext.getCurrentInstance();
        boolean resultado = true;
        this.manager.guardarParteTrabajo(this.parteTrabajoDto, this.dto);
        context.addCallbackParam("CallbackParam", resultado);
    }

    /**
     * handleProductoChange(): actualiza la unidad de medida al seleccionar un
     * producto diferente
     *
     * @since 10/01/2014
     */
    public void handleProductoChange() {
        this.detaProdDto.setUnidadMedidaDto(this.detaProdDto.getProductoDetaDto().getUnidadMedidaDto());
    }

    /**
     * onBlurCantidad(): asigna el costo componente, equivalente al producto de
     * la cantidad movida multiplicado por el precio de compra del producto
     *
     * @since 10/01/2014
     */
    public void onBlurCantidad() {
        this.detaProdDto.setCostoComponente(this.detaProdDto.getCantidadMovida().multiply(this.detaProdDto.getProductoDetaDto().getPrecioCompra()));
    }

    public ApplicationMBean getApplicationMBean() {
        return applicationMBean;
    }

    public void setApplicationMBean(ApplicationMBean applicationMBean) {
        this.applicationMBean = applicationMBean;
    }

    public OrdenFabDto getDto() {
        return dto;
    }

    public void setDto(OrdenFabDto dto) {
        this.dto = dto;
    }

    public OrdenFabDto getDtoFiltro() {
        return dtoFiltro;
    }

    public void setDtoFiltro(OrdenFabDto dtoFiltro) {
        this.dtoFiltro = dtoFiltro;
    }

    public String getKeyTitulo() {
        return keyTitulo;
    }

    public void setKeyTitulo(String keyTitulo) {
        this.keyTitulo = keyTitulo;
    }

    public List<OrdenFabDto> getLista() {
        return lista;
    }

    public void setLista(List<OrdenFabDto> lista) {
        this.lista = lista;
    }

    public static Logger getLogger() {
        return logger;
    }

    public static void setLogger(Logger logger) {
        OrdenFabricacionMBean.logger = logger;
    }

    public RecursosManager getRecursosManager() {
        return recursosManager;
    }

    public void setRecursosManager(RecursosManager recursosManager) {
        this.recursosManager = recursosManager;
    }

    public SessionMBean getSessionMBean() {
        return sessionMBean;
    }

    public void setSessionMBean(SessionMBean sessionMBean) {
        this.sessionMBean = sessionMBean;
    }

    public ArchivoMBean getArchivoMBean() {
        return archivoMBean;
    }

    public void setArchivoMBean(ArchivoMBean archivoMBean) {
        this.archivoMBean = archivoMBean;
    }

    public OrdenFabricacionManager getManager() {
        return manager;
    }

    public void setManager(OrdenFabricacionManager manager) {
        this.manager = manager;
    }

    public BitacoraManager getBitacoraManager() {
        return bitacoraManager;
    }

    public void setBitacoraManager(BitacoraManager bitacoraManager) {
        this.bitacoraManager = bitacoraManager;
    }

    public List<PlanProduccionDto> getListaPlanProduccion() throws DAOException {
        PlanProduccionManager ppManager = (PlanProduccionManager) WebServletContextListener.getApplicationContext().getBean("planProduccionManager");
        this.listaPlanProduccion = ppManager.obtenerActivos();
        return this.listaPlanProduccion;
    }

    public void setListaPlanProduccion(List<PlanProduccionDto> listaPlanProduccion) {
        this.listaPlanProduccion = listaPlanProduccion;
    }

    public OrdenFabOperacionDto getDetaOpDto() {
        return detaOpDto;
    }

    public void setDetaOpDto(OrdenFabOperacionDto detaOpDto) {
        this.detaOpDto = detaOpDto;
    }

    public List<PlanProduccionOperacionDto> getListaOperacion() throws DAOException {
        PlanProduccionOperacionManager ppOManager = (PlanProduccionOperacionManager) WebServletContextListener.getApplicationContext().getBean("planProduccionOperacionManager");
        this.listaOperacion = ppOManager.obtenerTodos();
        return this.listaOperacion;
    }

    public void setListaOperacion(List<PlanProduccionOperacionDto> listaOperacion) {
        this.listaOperacion = listaOperacion;
    }

    public List<ProcesoDto> getListaProceso() throws DAOException {
        ProcesoManager procesoManager = (ProcesoManager) WebServletContextListener.getApplicationContext().getBean("procesoManager");
        this.listaProceso = procesoManager.obtenerActivos();
        return this.listaProceso;
    }

    public void setListaProceso(List<ProcesoDto> listaProceso) {
        this.listaProceso = listaProceso;
    }

    public OrdenFabProductoDto getDetaProdDto() {
        return detaProdDto;
    }

    public void setDetaProdDto(OrdenFabProductoDto detaProdDto) {
        this.detaProdDto = detaProdDto;
    }

    public List<ParametroDto> getListaTipoProducto() throws DAOException {
        ParametroManager parametroManager = (ParametroManager) WebServletContextListener.getApplicationContext().getBean("parametroManager");
        this.listaTipoProducto = parametroManager.obtenerParametrosActivosPorCatalogoSistema(427L);
        return this.listaTipoProducto;
    }

    public void setListaTipoProducto(List<ParametroDto> listaTipoProducto) {
        this.listaTipoProducto = listaTipoProducto;
    }

    public List<UnidadMedidaDto> getListaUom() throws DAOException {
        UnidadMedidaManager umManager = (UnidadMedidaManager) WebServletContextListener.getApplicationContext().getBean("unidadMedidaManager");
        this.listaUom = umManager.obtenerTodosActivos();
        return this.listaUom;
    }

    public void setListaUom(List<UnidadMedidaDto> listaUom) {
        this.listaUom = listaUom;
    }

    public ParteTrabajoDto getParteTrabajoDto() {
        return parteTrabajoDto;
    }

    public void setParteTrabajoDto(ParteTrabajoDto parteTrabajoDto) {
        this.parteTrabajoDto = parteTrabajoDto;
    }
}
